﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Hammock;
using Hammock.Authentication.OAuth;
using Newtonsoft.Json.Linq;
using WeiboPlus.Models;
using WeiboPlus.Service;

namespace WeiboPlus.Tencent
{
    public class TencentUserService : UserServiceBase
    {
        protected override RestClient CreateRestClient()
        {
            return new RestClient
            {
                Authority = "http://open.t.qq.com",   // Tencent调用API的时候不是用的https协议，这点和获取Token方式不同
                HasElevatedPermissions = true
            };
        }

        protected override void Initialize()
        {
            GET_CURRENT_USER = "/api/user/info?format=json";
            GET_USER = "/api/user/other_info?format=json";
            FOLLOW_USER = "/api/friends/add?format=json";
            UNFOLLOW_USER = "/api/friends/del?format=json";
            FRIENDSHIP = "";
            GET_USER_LIST = "/api/user/infos?format=json";
            GET_FANS = "/api/friends/fanslist?format=json";
            GET_FANS_LITE = "/api/friends/fanslist_s?format=json";
            GET_IDOLS = "/api/friends/idollist?format=json";
            GET_IDOLS_LITE = "/api/friends/idollist_s?format=json";
            GET_USER_FANS = "/api/friends/user_fanslist?format=json";
            GET_USER_IDOLS = "/api/friends/user_idollist?format=json";
            GET_USER_SPECIALS = "/api/friends/user_speciallist_s?format=json";
            SEARCH_USER = "/api/search/user?format=json";
        }

        protected override string[] GetParamtersList(SNSType type)
        {
            string[] list;
            switch (type)
            {
                case SNSType.SingleUser:
                    list = new string[] { 
                        SNSParametersConstants.NAME
                    };
                    break;
                case SNSType.Friends:
                    list = new string[] { 
                        SNSParametersConstants.FORMAT,
                        SNSParametersConstants.REQ_NUM,
                        SNSParametersConstants.START_INDEX,
                        SNSParametersConstants.NAME,
                    };
                    break;
                case SNSType.Followers:
                    list = new string[] { 
                        SNSParametersConstants.FORMAT,
                        SNSParametersConstants.REQ_NUM,
                        SNSParametersConstants.START_INDEX,
                        SNSParametersConstants.NAME,
                    };
                    break;
                case SNSType.UserFriends:
                    list = new string[] { 
                        SNSParametersConstants.FORMAT,
                        SNSParametersConstants.REQ_NUM,
                        SNSParametersConstants.START_INDEX,
                        SNSParametersConstants.NAME,
                    };
                    break;
                case SNSType.UserFollowers:
                    list = new string[] { 
                        SNSParametersConstants.FORMAT,
                        SNSParametersConstants.REQ_NUM,
                        SNSParametersConstants.START_INDEX,
                        SNSParametersConstants.NAME,
                    };
                    break;
                case SNSType.HotPeople:
                    return new string[]
                    { 
                        SNSParametersConstants.CONTENT,
                        SNSParametersConstants.CLIENT_IP,
                        SNSParametersConstants.JING,
                        SNSParametersConstants.WEI,
                        SNSParametersConstants.REID
                    };
                case SNSType.Follow:
                    return new string[]
                    { 
                        SNSParametersConstants.CLIENT_IP,
                        SNSParametersConstants.NAME
                    };

                case SNSType.UnFollow:
                    return new string[]
                    { 
                        SNSParametersConstants.CLIENT_IP,
                        SNSParametersConstants.NAME
                    };
                case SNSType.SuggestionPeoples:
                    list = new string[] { 
                        //SNSParametersConstants.COUNT,
                        //SNSParametersConstants.BASE_APP
                    };
                    break;
                case SNSType.SearchUser:
                    list = new string[] { 
                        //SNSParametersConstants.COUNT,
                        //SNSParametersConstants.BASE_APP
                        SNSParametersConstants.KEY_WORD,
                        SNSParametersConstants.PAGE_SIZE,
                        SNSParametersConstants.PAGE
                    };
                    break;
                default:
                    list = new string[] { };
                    break;
            }
            return list;
        }

        protected override System.Collections.Generic.IList<SNSUser> Mapping(string res, SNSResult result)
        {
            JObject o = JObject.Parse(res);

            List<SNSUser> users = o.SelectToken("data.info").Select(
                s => Factory.GetMapping<JToken, SNSUser>().Map(s)
                ).ToList();
            return users;
        }

        protected override System.Collections.Generic.IList<T1> Mapping<T1>(string res, SNSResult result)
        {
            JObject o = JObject.Parse(res);

            List<T1> users = o.SelectToken("data.info").Select(
                s => Factory.GetMapping<JToken, T1>().Map(s)
                ).ToList();
            return users;
        }

        protected override SNSUser MappingSingle(string res,SNSResult result)
        {
            JObject o = JObject.Parse(res);

            SNSUser user = Factory.GetMapping<JToken, SNSUser>().Map(o.SelectToken("data"));
                
            return user;
        }

        protected override Hammock.Authentication.IWebCredentials CreateCredential()
        {
            var credantial = base.CreateCredential() as OAuthCredentials;
            credantial.ParameterHandling = OAuthParameterHandling.UrlOrPostParameters;
            return credantial;
        }

        protected int ValidateResponse(string content, out string msg)
        {
            //return base.ValidateResponse(o, out msg);
            //o.Content
            var jo = JObject.Parse(content);
            if (jo == null)
            {
                msg = "object type no match";
                return 0;
            }

            //TO-DO ERROE HANDLE
            var errcode = (int)jo.SelectToken("errcode");
            var ret = (int)jo.SelectToken("ret");

            if (jo.SelectToken("data.pageinfo") != null)
                msg = "pageinfo|" + (string)jo.SelectToken("data.pageinfo");
            else if (jo.SelectToken("msg") != null)
                msg = (string)jo.SelectToken("msg");
            else
                msg = content;

            bool isvalid = errcode == 0 && ret == 0 && !msg.Contains("have no");

            if (msg.Contains("have no"))
                return 99;

            if (isvalid)
                return 1;
            else
                return 0;
        }

        protected override int ValidateResponse(RestResponse o, out string msg)
        {
            //return base.ValidateResponse(o, out msg);
            //o.Content
            if (o.Content.StartsWith("<"))
            {
                msg = o.Content;
                return 0;
            }

            var jo = JObject.Parse(o.Content);
            if (jo == null)
            {
                msg = "object type no match";
                return 0;
            }

            //TO-DO ERROE HANDLE
            int errcode = 0, ret = 0;
            if (jo.SelectToken("errcode") != null)
                errcode = (int)jo.SelectToken("errcode");
            if (jo.SelectToken("errcode") != null)
                ret = (int)jo.SelectToken("ret");

            if (jo.SelectToken("data.pageinfo") != null)
                msg = "pageinfo|" + (string)jo.SelectToken("data.pageinfo");
            else if (jo.SelectToken("msg") != null)
                msg = (string)jo.SelectToken("msg");
            else
                msg = o.Content;

            bool isvalid = errcode == 0 && ret == 0 && !msg.Contains("have no");

            if (msg.Contains("have no"))
                return 99;

            if (isvalid)
                return 1;
            else
                return 0;
        }

    }
}
